Desktop App Hosting Setup Guide
This guide walks through setting up Cloudflare R2 hosting for desktop app downloads.
Overview
- **Build System**: Tauri (Rust + Web frontend)
- **Storage**: Cloudflare R2 (S3-compatible)
- **CDN**: Cloudflare Workers (optional, for faster downloads)
- **Platforms**: macOS (dmg), Windows (msi/exe), Linux (deb/AppImage)
Prerequisites
- **Cloudflare Account** with R2 enabled
- **Rust** and **Node.js** installed locally
- **Tauri CLI**:
cargo install tauri-cli --version "^2.0.0"
Step 1: Create Cloudflare R2 Bucket
1.1 Create Bucket
# Install wrangler CLI
npm install -g wrangler
# Login to Cloudflare
wrangler login
# Create R2 bucket
wrangler r2 bucket create atom-desktop-app1.2 Get Your Account ID
# Your account ID is shown after login
# Or find it in Cloudflare dashboard: https://dash.cloudflare.com → Right sidebarStep 2: Configure R2 Access Tokens
2.1 Create R2 API Token
- Go to: https://dash.cloudflare.com → R2 → Manage R2 API Tokens
- Create a new API token with permissions:
- **Read** access to
atom-desktop-appbucket - **Write** access to
atom-desktop-appbucket - **List** access to buckets
- Copy the **Access Key ID** and **Secret Access Key**
2.2 Set Environment Variables
Add to your .env file or Vault secrets:
# Cloudflare R2 Configuration (Desktop App Storage)
DESKTOP_R2_ACCOUNT_ID=your_account_id_here
DESKTOP_R2_ACCESS_KEY=your_access_key_id_here
DESKTOP_R2_SECRET_KEY=your_secret_access_key_here
DESKTOP_R2_BUCKET=atom-desktop-app**Important**: These secrets use DESKTOP_R2_ prefix to avoid conflicts with other R2 buckets (e.g., tenant file storage).
For Cloud deployment:
# Desktop app storage secrets
atom-cli secrets set DESKTOP_R2_ACCOUNT_ID=...
atom-cli secrets set DESKTOP_R2_ACCESS_KEY=...
atom-cli secrets set DESKTOP_R2_SECRET_KEY=...
atom-cli secrets set DESKTOP_R2_BUCKET=atom-desktop-appStep 3: Set Up Custom Domain (Optional)
3.1 Configure R2 Custom Domain
# Create a public bucket for custom domain access
wrangler r2 bucket put atom-desktop-app --public3.2 Add Custom Domain in Cloudflare Dashboard
- Go to: https://dash.cloudflare.com → R2 → atom-desktop-app
- Click "Settings" → "Public Access"
- Add custom domain:
r2.atom-saas.com(or your subdomain) - Configure DNS: Add CNAME record pointing to R2
3.3 DNS Configuration
Type: CNAME
Name: r2 (or your subdomain)
Target: [Cloudflare provides target]
Proxy: Yes (DNS only)Step 4: Build Desktop App
4.1 Development Build
# Run with hot reload
npm run desktop:dev4.2 Production Build
# Build for current platform
npm run desktop:build
# Build specific platform
npm run desktop:build:macos # macOS universal binary
npm run desktop:build:windows # Windows x64
npm run desktop:build:linux # Linux x64Build artifacts are created in:
- macOS:
src-tauri/target/release/bundle/dmg/ - Windows:
src-tauri/target/release/bundle/msi/orbundle/nsis/ - Linux:
src-tauri/target/release/bundle/deb/orbundle/appimage/
Step 5: Upload to R2
5.1 Upload Build Artifacts
# Upload version 1.0.0 builds to R2
npm run desktop:upload:r2
# Or specify custom version
npx tsx scripts/upload-to-r2.ts 1.0.1This will:
- Upload all artifacts from
desktop-builds/1.0.0/ - Create SHA256 checksums for each file
- Upload
version.jsonwith build metadata - Update
versions.jsonmanifest - Set
latest-version.jsonpointer
5.2 Manual Upload (Alternative)
# Install AWS CLI (works with R2)
brew install awscli
# Configure AWS CLI for R2
aws configure set \
--profile desktop_r2 \
--endpoint-url https://${DESKTOP_R2_ACCOUNT_ID}.r2.cloudflarestorage.com
# Upload a file
aws s3 cp \
./Atom-SaaS-1.0.0.dmg \
s3://atom-desktop-app/desktop-apps/1.0.0/Atom-SaaS-1.0.0.dmg \
--profile desktop_r2 \
--endpoint-url https://${DESKTOP_R2_ACCOUNT_ID}.r2.cloudflarestorage.comStep 6: Download API
6.1 Test Download API
# Get latest version for auto-detected platform
curl "https://[tenant].atomagentos.com/api/desktop/download"
# Get specific platform
curl "https://[tenant].atomagentos.com/api/desktop/download?platform=darwin"
# Get specific version
curl "https://[tenant].atomagentos.com/api/desktop/download?platform=darwin&version=1.0.0"6.2 Response Format
{
"version": "1.0.0",
"platform": "darwin",
"artifact": "Atom-SaaS-1.0.0.dmg",
"downloadUrl": "https://r2.atom-saas.com/desktop-apps/1.0.0/Atom-SaaS-1.0.0.dmg",
"checksumUrl": "https://r2.atom-saas.com/desktop-apps/1.0.0/Atom-SaaS-1.0.0.dmg.sha256",
"releaseNotes": "https://github.com/rush86999/atom-saas/releases/tag/v1.0.0"
}Step 7: Integrate with Onboarding
The <DesktopDownload /> component is already integrated into the onboarding flow (Step 6 - Local Bridge Setup).
Users can download the desktop app during onboarding, which provides:
- Local terminal control
- Browser automation via Playwright
- Background agent execution
- 0 ACU consumption for local operations
Troubleshooting
Build Fails
# Check Rust installation
rustc --version # Should be 1.70+ for Tauri 2.x
# Check Node.js version
node --version # Should be 18+
# Clear build cache
cd src-tauri
cargo cleanUpload Fails
# Verify credentials
echo $DESKTOP_R2_ACCOUNT_ID
echo $DESKTOP_R2_ACCESS_KEY
# Test R2 connection
aws s3 ls \
s3://atom-desktop-app/ \
--profile desktop_r2 \
--endpoint-url https://${DESKTOP_R2_ACCOUNT_ID}.r2.cloudflarestorage.comDownload API Returns Error
# Check environment variables are set
atom-cli secrets list | grep DESKTOP_R2
# Test R2 bucket access
curl "https://r2.atom-saas.com/desktop-apps/latest-version.json"Code Signing (Production)
For distribution outside your organization, you need code signing:
**macOS**: Apple Developer certificate
# In src-tauri/tauri.conf.json:
"macOS": {
"signingIdentity": "Developer ID Application: YOUR_NAME (TEAM_ID)"
}**Windows**: Code signing certificate
# Install signtool on Windows
# Add certificate thumbprint to src-tauri/tauri.conf.json
"windows": {
"certificateThumbprint": "YOUR_CERTIFICATE_THUMBPRINT"
}File Structure After Build
desktop-builds/
└── 1.0.0/
├── Atom-SaaS-1.0.0.dmg
├── Atom-SaaS-1.0.0.dmg.sha256
├── Atom-SaaS-1.0.0-setup.exe
├── Atom-SaaS-1.0.0-setup.exe.sha256
├── atom-saas-1.0.0-amd64.deb
├── atom-saas-1.0.0-amd64.deb.sha256
└── version.jsonR2 Bucket Structure
atom-desktop-app/
├── desktop-apps/
│ ├── latest-version.json → Symlink/pointer to current version
│ ├── versions.json → All available versions
│ └── 1.0.0/
│ ├── Atom-SaaS-1.0.0.dmg
│ ├── Atom-SaaS-1.0.0.dmg.sha256
│ ├── Atom-SaaS-1.0.0-setup.exe
│ ├── Atom-SaaS-1.0.0-setup.exe.sha256
│ ├── atom-saas-1.0.0-amd64.deb
│ ├── atom-saas-1.0.0-amd64.deb.sha256
│ └── version.json
└── [future versions...]Cost Estimates
**R2 Storage**: ~$0.015/GB/month
- Each build ~150MB (all platforms)
- 10 versions = 1.5GB = ~$0.02/month
**R2 Egress** (Class A): ~$0.009/GB (first 10TB) in US
- 1000 downloads × 150MB = 150GB = ~$1.35
**Total**: Under $2/month for 1000 downloads
Next Steps
- Build your first desktop app:
npm run desktop:build - Upload to R2:
npm run desktop:upload:r2 - Test download API:
curl /api/desktop/download - Integrate with onboarding flow (already done)
- Set up custom domain for CDN (optional)